using Unity.Burst.Intrinsics;
using Unity.Collections;
using Unity.Entities;
using Unity.Entities.Internal;

namespace Game.Core
{
    public unsafe partial struct PropertyChangedJob : IJobEntity
    {
        public EntityCommandBuffer.ParallelWriter ECBParallel;
    
        void Execute(Entity entity, [EntityIndexInQuery] int index, in PropertyChangedEvent evt)
        {
            EventScheduler<PropertyChangedEvent>.EventHandler?.Invoke(entity, evt);
            ECBParallel.DestroyEntity(index, entity);
        }
    }
    
    public unsafe partial struct InvokeEventJob<TEvent> : IJobChunk
        where TEvent : unmanaged, IComponentData
    {
        public EntityCommandBuffer.ParallelWriter ECBParallel;
    
        [ReadOnly] public EntityTypeHandle EntityTypeHandle;
        public ComponentTypeHandle<TEvent> EventTypeHandle;
    
        public void Execute(in ArchetypeChunk batch, int unfilteredChunkIndex, bool useEnabledMask, in v128 chunkEnabledMask)
        {
            var entityPointer = InternalCompilerInterface.UnsafeGetChunkEntityArrayIntPtr(batch, EntityTypeHandle);
            var eventData = InternalCompilerInterface.UnsafeGetChunkNativeArrayIntPtr<TEvent>(batch, ref EventTypeHandle);
            int count = batch.Count;
            int baseEntityIndex = unfilteredChunkIndex;
            for (int i = 0; i < count; ++i)
            {
                var entity = InternalCompilerInterface.UnsafeGetCopyOfNativeArrayPtrElement<Entity>(entityPointer, i);
                var index = baseEntityIndex + i;
                ref var eventDataRef = ref InternalCompilerInterface.UnsafeGetRefToNativeArrayPtrElement<TEvent>(eventData, i);
                EventScheduler<TEvent>.EventHandler?.Invoke(entity, eventDataRef);
                ECBParallel.DestroyEntity(index, entity);
            }
        }

        
    }

    public struct EventDispatcher<TEvent> where TEvent : struct, IComponentData
    {
        EntityArchetype m_Archetype;
        EntityCommandBuffer.ParallelWriter m_ECBParallel;

        public EventDispatcher(EntityArchetype archetype, EntityCommandBuffer ecb)
        {
            m_Archetype = archetype;
            m_ECBParallel = ecb.AsParallelWriter();
        }

        public void Dispatch(int index)
        {
            m_ECBParallel.CreateEntity(index, m_Archetype);
        }

        // public void Dispatch(int index, TEvent evt)
        // {
        //     Entity entity = m_ECBParallel.CreateEntity(index, m_Archetype);
        //     m_ECBParallel.SetComponent(index, entity, evt);
        // }

    }
}